#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
package ${package}.${parentArtifactId}.modules.sys.service.impl;

import org.apache.commons.collections.CollectionUtils;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ${package}.${parentArtifactId}.modules.sys.dto.SysOrgDTO;
import ${package}.${parentArtifactId}.modules.sys.vo.SysOrgVo;
import ${package}.${parentArtifactId}.modules.sys.converter.SysOrgConverter;
import ${package}.${parentArtifactId}.modules.sys.vo.SysOrgTreeVo;
import ${package}.${parentArtifactId}.common.enums.ErrorCodeEnum;
import ${package}.${parentArtifactId}.common.util.AssertUtil;
import ${package}.${parentArtifactId}.common.validator.DataValidator;
import ${package}.${parentArtifactId}.modules.sys.entity.SysOrg;
import ${package}.${parentArtifactId}.modules.sys.mapper.SysOrgMapper;
import ${package}.${parentArtifactId}.modules.sys.service.SysOrgService;
import org.springframework.stereotype.Service;
import ${package}.${parentArtifactId}.common.bean.PageData;
import ${package}.${parentArtifactId}.common.bean.PageParam;
import java.util.ArrayList;
import java.util.List;

/**
 * @Classname SysOrgServiceImpl
 * @Description SysOrgService实现类
 * @Author Created by xudp (alias:孤傲苍狼) 290603672@qq.com
 * @Date 2020-10-15
 * @Version 1.0
 */
@Service
public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> implements SysOrgService {

    @Override
    public void create(SysOrgDTO sysOrgDTO) {
        dataValidator.validate(sysOrgDTO);//业务处理校验
        SysOrg sysOrg = SysOrgConverter.build().entity(sysOrgDTO);//DTO转换成Entity
        save(sysOrg);//保存
    }

    @Override
    public void update(SysOrgDTO sysOrgDTO) {
        dataValidator.validate(sysOrgDTO);//业务处理校验
        SysOrg sysOrg = SysOrgConverter.build().entity(sysOrgDTO);//DTO转换成Entity
        updateById(sysOrg);
    }
    /**
    * 导入数据
    * @param dataList
    * @param isCovered
    */
    @Override
    public void importData(List<SysOrgDTO> dataList, Boolean isCovered) {
        dataList.forEach(sysOrgDTO -> {
            if(isCovered) {
                SysOrg oldData = null;//todo 根据条件查询旧数据
                if (oldData != null && oldData.getId() != null) {
                    //找到了就覆盖旧数据
                    sysOrgDTO.setId(oldData.getId());
                    update(sysOrgDTO);
                }else{
                    //找不到就新增
                    create(sysOrgDTO);
                }
            }else {
                create(sysOrgDTO);
            }
        });
    }
 
    @Override
    public void deleteById(Long id) {
        removeById(id);//逻辑删除
    }

    @Override
    public void deleteByIds(List<Long> idList) {
        removeByIds(idList);//逻辑删除
    }

    @Override
    public SysOrgVo getSysOrgById(Long id) {
        SysOrg sysOrg = getById(id);
        AssertUtil.notNull(ErrorCodeEnum.DATA_NOT_EXIST,sysOrg);
        return SysOrgConverter.build().vo(sysOrg);
    }

    @Override
    public void delete(QueryWrapper<SysOrg> queryWrapper) {
        remove(queryWrapper);
    }

    @Override
    public void deleteAll() {
        remove(null);//全部删除(逻辑删除)
    }

    @Override
    public List<SysOrgVo> getList(QueryWrapper<SysOrg> queryWrapper) {
        List<SysOrg> sysOrgList = list(queryWrapper);
        return SysOrgConverter.build().listVO(sysOrgList);
    }

    @Override
    public PageData<SysOrgVo> pageList(Page<SysOrg> page, QueryWrapper<SysOrg> queryWrapper) {
        IPage<SysOrg> pageInfo = page(page,queryWrapper);//mybatisPlus分页查询
        IPage<SysOrgVo> pageVO = SysOrgConverter.build().pageVO(pageInfo);
        return PageData.build(pageVO);
    }

    @Override
    public PageData<SysOrgVo> pageList(PageParam pageParam, QueryWrapper<SysOrg> queryWrapper) {
        Page<SysOrg> page = new Page<>(pageParam.getPageNum(),pageParam.getPageSize());
        return pageList(page,queryWrapper);
    }


    /**
    * 根据ID获取信息以及子节点列表
    * @param id
    * @return
    */
    @Override
    public List<SysOrgTreeVo> getSubNodeListById(Long id){
        SysOrg sysOrg = getById(id);
        AssertUtil.notNull(ErrorCodeEnum.DATA_NOT_EXIST,sysOrg);
        SysOrgTreeVo treeVo = SysOrgConverter.build().treeVo(sysOrg);
        List<SysOrgTreeVo> treeVoList = new ArrayList<>();
        treeVoList.add(treeVo);
        recursionQuerySubNode(treeVoList,treeVo.getId());//递归查询子节点
        return treeVoList;
    }

    /**
     * 根据ID获取父节点列表
     * @param id
     * @return
     */
    @Override
    public List<SysOrgTreeVo> getParentNodeTreeListById(Long id){
        List<SysOrgTreeVo> treeVoList = new ArrayList<>();
        SysOrg sysOrg = getById(id);
        recursionQueryParentNode(treeVoList,sysOrg);
        return treeVoList;
    }

    /**
     * 根据ID获取树
     * @param id
     * @return
     */
    @Override
    public SysOrgTreeVo getTreeById(Long id){
        SysOrg sysOrg = getById(id);
        AssertUtil.notNull(ErrorCodeEnum.DATA_NOT_EXIST,sysOrg);
        SysOrgTreeVo treeVo = SysOrgConverter.build().treeVo(sysOrg);
        recursionQuerySubNode(treeVo);//递归查询子节点
        return treeVo;
    }

    @Override
    public List<SysOrgTreeVo> getTreeVoList(QueryWrapper<SysOrg> queryWrapper){
        List<SysOrg> sysOrgList = list(queryWrapper);
        return SysOrgConverter.build().treeListVo(sysOrgList);
    }

    /**
    * 递归查询子节点
    */
    private void recursionQuerySubNode(SysOrgTreeVo treeNodeVo){
        Long id = treeNodeVo.getId();
        //根据parentId查询
        List<SysOrgTreeVo> childrenVoList = new ArrayList<>();
        //查找子节点信息
        List<SysOrg> subNodeList = query().eq(SysOrg.PARENT_ID,id).list();
        if(CollectionUtils.isNotEmpty(subNodeList)){
            //子节点信息不为空
            for(SysOrg sysOrg:subNodeList) {
                SysOrgTreeVo treeVo = SysOrgConverter.build().treeVo(sysOrg);
                childrenVoList.add(treeVo);
            }
            for(SysOrgTreeVo treeVo:childrenVoList){
                //递归查询
                recursionQuerySubNode(treeVo);
            }
        }
        treeNodeVo.setChildren(childrenVoList);
    }

    /**
    * 递归查询子节点信息
    * @param voList
    * @param parentId
    */
    private void recursionQuerySubNode(List<SysOrgTreeVo> voList, Long parentId){
        //根据parentId查询子节点信息
        List<SysOrg> subNodeList = query().eq(SysOrg.PARENT_ID,parentId).list();
        if(CollectionUtils.isNotEmpty(subNodeList)){
            List<SysOrgTreeVo> childrenVoList = new ArrayList<>();
            //子节点信息不为空
            for(SysOrg sysOrg:subNodeList) {
                SysOrgTreeVo treeVo = SysOrgConverter.build().treeVo(sysOrg);
                childrenVoList.add(treeVo);
            }
            voList.addAll(childrenVoList);
            for(SysOrgTreeVo treeVo:childrenVoList){
                List<SysOrgTreeVo> childrenList = new ArrayList<>();
                //递归查询
                recursionQuerySubNode(childrenList,treeVo.getId());
                voList.addAll(childrenList);
            }
        }
    }

    /**
     * 递归查询父节点
     * @param voList
     * @param sysOrg
     */
    private void recursionQueryParentNode(List<SysOrgTreeVo> voList, SysOrg sysOrg){
        //根据Id查询父节点
        if(sysOrg.getParentId()!=null){
            SysOrg parentNode = getById(sysOrg.getParentId());
            SysOrgTreeVo parentNodeTreeVo = SysOrgConverter.build().treeVo(parentNode);
            voList.add(parentNodeTreeVo);
            //递归
            recursionQueryParentNode(voList,parentNode);
        }
    }

    /**
     * 数据校验器
     */
    private DataValidator<SysOrgDTO> dataValidator = new DataValidator<SysOrgDTO>(){

        /**
        * 数据合法性校验(非空、数据格式等)
        * @param data
        */
        @Override
        protected void validateData(SysOrgDTO data) {
            //todo:在这里编写数据校验处理逻辑，如果校验不通过，抛出DataValidationException异常
            // throw new DataValidationException("校验不通过抛出的错误提示消息");
        }

        /**
         * 保存之前进行校验(例如：数据是否已存在校验)
         * @param data
         */
        @Override
        protected void beforeCreate(SysOrgDTO data) {

        }

        /**
         * 更新之前进行校验(例如：数据是否已存在校验)
         * @param data
         */
        @Override
        protected void beforeUpdate(SysOrgDTO data) {

        }
    };
}
